home *** CD-ROM | disk | FTP | other *** search
/ .net 2002 March / DotNetMagazine-Issue107-Coverdisc-NET107-02-03-PCMac.bin / pc / PC Software / picks / HTTrack / httrack-3.22-3.exe / {app} / src_win / WinHTTrack / DirTreeView.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2002-10-18  |  20.0 KB  |  747 lines

  1. // DirTreeView.cpp : implementation file
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "winhttrack.h"
  6. #include "DirTreeView.h"
  7.  
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13.  
  14. #include "htsbase.h"
  15.  
  16. #include "MainFrm.h"
  17.  
  18. CDirTreeView* this_DirTreeView=NULL;
  19.  
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CDirTreeView
  22.  
  23. IMPLEMENT_DYNCREATE(CDirTreeView, CTreeView)
  24.  
  25. CDirTreeView::CDirTreeView()
  26. {
  27.   this_DirTreeView=this;
  28.   redraw_in_progress=0;
  29.   timer=0;
  30.   count_whandle=0;
  31.   docType="<nullType>";
  32. }
  33.  
  34. CDirTreeView::~CDirTreeView()
  35. {
  36.   WaitThreads();
  37.   this_DirTreeView=NULL;
  38.   if (imagelist.m_hImageList) {
  39.     imagelist.Detach();
  40.     imagelist.m_hImageList=NULL;
  41.   }
  42. }
  43.  
  44.  
  45. BEGIN_MESSAGE_MAP(CDirTreeView, CTreeView)
  46.     //{{AFX_MSG_MAP(CDirTreeView)
  47.     ON_WM_TIMER()
  48.     ON_WM_SHOWWINDOW()
  49.     ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding)
  50.     ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
  51.     ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick)
  52.     ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnEndlabeledit)
  53.     ON_NOTIFY_REFLECT(TVN_KEYDOWN, OnKeydown)
  54.     ON_NOTIFY_REFLECT(NM_CLICK, OnClick)
  55.     ON_WM_KILLFOCUS()
  56.     ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
  57.     //}}AFX_MSG_MAP
  58. END_MESSAGE_MAP()
  59.  
  60. /////////////////////////////////////////////////////////////////////////////
  61. // CDirTreeView drawing
  62.  
  63. void CDirTreeView::OnDraw(CDC* pDC)
  64. {
  65.     CDocument* pDoc = GetDocument();
  66.     // TODO: add draw code here
  67. }
  68.  
  69. /////////////////////////////////////////////////////////////////////////////
  70. // CDirTreeView diagnostics
  71.  
  72. #ifdef _DEBUG
  73. void CDirTreeView::AssertValid() const
  74. {
  75.     CTreeView::AssertValid();
  76. }
  77.  
  78. void CDirTreeView::Dump(CDumpContext& dc) const
  79. {
  80.     CTreeView::Dump(dc);
  81. }
  82. #endif //_DEBUG
  83.  
  84. /////////////////////////////////////////////////////////////////////////////
  85. // CDirTreeView message handlers
  86.  
  87.  
  88. BOOL CDirTreeView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
  89. {
  90.   dwStyle|=(TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_SHOWSELALWAYS|TVS_EDITLABELS);
  91.   //dwStyle|=(TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_SHOWSELALWAYS|TVS_DISABLEDRAGDROP);
  92.   //
  93.   dwStyle&=(~(TVS_NOTOOLTIPS));     /* disabled */
  94.  
  95. /*
  96.   dwStyle|=(WS_DISABLED);
  97.   dwStyle&=(~(WS_VISIBLE));
  98. */
  99.  
  100.   int r=CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
  101.  
  102.   GetTreeCtrl().SetImageList(&imagelist,TVSIL_NORMAL);
  103.   /*GetTreeCtrl().SetToolTips(&m_TreeViewToolTip);*/
  104.  
  105.   RefreshTree();
  106.   return r;
  107. }
  108.  
  109.  
  110. void CDirTreeView::RefreshTree() {
  111.   CTreeCtrl& tree=GetTreeCtrl();
  112.   if (!tree) return;   /* error */
  113.  
  114.   tree.DeleteAllItems();
  115.   int len=32768;
  116.   char* adr=(char*)malloc(len+4);
  117.   if (adr) {
  118.     if (GetLogicalDriveStrings(len,adr)>0) {
  119.       char*a=adr;
  120.       while(*a) {
  121.         char* next=a+strlen(a)+1;
  122.         if (*(a+strlen(a)-1)=='\\')
  123.           *(a+strlen(a)-1)='\0';
  124.         HTREEITEM it=tree.InsertItem(a);
  125.         if (it) {
  126.           tree.SetItemText(it,"");
  127.           tree.InsertItem("expanding..",it,TVI_SORT);
  128.          
  129.           // icone
  130.           char name[256];
  131.           strcpybuff(name,a);
  132.           strcatbuff(name,"\\");
  133.           SHFILEINFO info;
  134.           if (SHGetFileInfo(name,0,&info,sizeof(info),SHGFI_SMALLICON | SHGFI_SYSICONINDEX | SHGFI_SHELLICONSIZE | SHGFI_DISPLAYNAME)) {
  135.             //SHGetFileInfo(name,0,&info,sizeof(info),SHGFI_SMALLICON | SHGFI_SYSICONINDEX | SHGFI_TYPENAME | SHGFI_SHELLICONSIZE | SHGFI_DISPLAYNAME | SHGFI_ATTRIBUTES); 
  136.             tree.SetItemImage(it,info.iIcon,info.iIcon);
  137.             CString disp=info.szDisplayName;
  138.             if (disp.ReverseFind('('))
  139.               disp=disp.Left(disp.Find('('));
  140.             disp+="<"; disp+=a; disp+=">"; 
  141.             tree.SetItemText(it,disp);
  142.           }
  143.         }
  144.  
  145.         a=next;
  146.       }
  147.     }
  148.     free(adr);
  149.   }
  150.   
  151.   BuildTrackHandles();
  152. }
  153.  
  154. /* remise ‡ zÈro */
  155. void CDirTreeView::ResetTree() {
  156.   if (!GetTreeCtrl()) return;   /* error */
  157.   RefreshTree();
  158.   StartTimer();
  159. }
  160.  
  161. /* attendre fin des threads refresh */
  162. void CDirTreeView::WaitThreads() {
  163.   /* attendre */
  164.   int w=0;
  165.   while((redraw_in_progress) && (w<10)) {
  166.     Sleep(100);
  167.     w++;
  168.   }
  169. }
  170.  
  171.  
  172. void CDirTreeView::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult) 
  173. {
  174.   *pResult = 0;
  175.   if (GetTreeCtrl().GetStyle() & WS_VISIBLE) {    /* sinon pas de refresh */
  176.     NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  177.     
  178.     // find out what item is getting expanded, and send that to Expand(hItem, TVE_EXPAND)
  179.     if (pNMTreeView->hdr.code == TVN_ITEMEXPANDING)
  180.     {
  181.       HTREEITEM hIT = pNMTreeView->itemNew.hItem;
  182.       DestroyTrackHandles();
  183.       if (!RefreshDir(hIT))
  184.         *pResult = 1;
  185.       BuildTrackHandles();
  186.     }
  187.   }
  188. }
  189.  
  190. void CDirTreeView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) 
  191. {
  192.   NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  193.   // find out what item is getting expanded, and send that to Expand(hItem, TVE_EXPAND)
  194.   if (pNMTreeView->hdr.code == TVN_SELCHANGED)
  195.   {
  196.     HTREEITEM hIT = pNMTreeView->itemNew.hItem;
  197.     CString st=GetItemPath(hIT);
  198.   
  199.     CWnd* top_window=this;
  200.     while(top_window->GetParent())
  201.       top_window=top_window->GetParent();
  202.     ((CMainFrame*)top_window)->m_wndStatusBar.SetWindowText(st);
  203.   }    
  204.   *pResult = 0;
  205. }
  206.  
  207.  
  208. void CDirTreeView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult) 
  209. {
  210.   HTREEITEM selected=GetTreeCtrl().GetSelectedItem();
  211.   if (selected) {
  212.     if (!GetTreeCtrl().ItemHasChildren(selected)) {
  213.       CString name=GetItemPath(selected);
  214.       if (name.Right(1)=="\\")
  215.         name=name.Left(name.GetLength()-1);
  216.       DWORD attrb=GetFileAttributes(name);
  217.       if (attrb!=0xFFFFFFFF) {
  218.         if ( !(attrb & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY)) ) {
  219.           CWaitCursor wait;
  220.           if (docType.CompareNoCase(name.Right(docType.GetLength()))==0) {
  221.             CWinApp* app=AfxGetApp();
  222.             POSITION pos;
  223.             pos=app->GetFirstDocTemplatePosition();
  224.             CDocTemplate* templ = app->GetNextDocTemplate(pos);
  225.             pos=templ->GetFirstDocPosition();
  226.             CDocument* doc  = templ->GetNextDoc(pos);
  227.             if (doc) {
  228.               //if (doc->SaveModified()) {
  229.               AfxGetApp()->OpenDocumentFile(name);
  230.               //}
  231.             }
  232.           } else {
  233.             /* Lancer ShellEx en arriËre plan */
  234.             AfxBeginThread(CDirTreeViewShellEx,new CString(name));
  235.           }
  236.         }
  237.       }
  238.     }
  239.   }
  240.   *pResult = 0;
  241. }
  242.  
  243. void CDirTreeView::OnClick(NMHDR* pNMHDR, LRESULT* pResult) 
  244. {
  245.   CTreeCtrl& tree=GetTreeCtrl();
  246.   if (!tree) return;
  247.  
  248.   HTREEITEM curr_selected=tree.GetDropHilightItem();
  249.   if (!curr_selected)
  250.     curr_selected=tree.GetSelectedItem();
  251.   if (curr_selected) {
  252.     /*
  253.     CString st=GetItemPath(curr_selected);
  254.   
  255.     CWnd* top_window=this;
  256.     while(top_window->GetParent())
  257.       top_window=top_window->GetParent();
  258.     ((CMainFrame*)top_window)->m_wndStatusBar.SetWindowText(st);
  259.     */
  260.   }
  261.  
  262.     *pResult = 0;
  263. }
  264.  
  265. void CDirTreeView::OnRclick(NMHDR* pNMHDR, LRESULT* pResult) 
  266. {
  267.   CTreeCtrl& tree=GetTreeCtrl();
  268.   if (!tree) return;
  269.   HTREEITEM curr_selected=tree.GetDropHilightItem();
  270.   if (!curr_selected)
  271.     curr_selected=tree.GetSelectedItem();
  272.   if (curr_selected) {
  273.     CString st=GetItemPath(curr_selected);
  274.     AfxMessageBox(st);
  275.   }
  276.   *pResult = 0;
  277. }
  278.  
  279.  
  280.  
  281. CString CDirTreeView::GetItemName(HTREEITEM position) {
  282.   CString st=GetTreeCtrl().GetItemText(position);
  283.   if (st.Find('<')) {
  284.     if (st.Right(2)==":>") {
  285.       st=st.Mid(st.Find('<')+1);
  286.       st=st.Left(st.GetLength()-1);
  287.     }
  288.   }
  289.   return st;
  290. }
  291.  
  292. CString CDirTreeView::GetItemPath(HTREEITEM position) {
  293.   if (position) {
  294.     HTREEITEM parent_it=GetTreeCtrl().GetParentItem(position);
  295.     CString st=GetItemName(position);
  296.     CString slash="";
  297.     if (GetTreeCtrl().ItemHasChildren(position))
  298.       slash="\\";
  299.     if (st.GetLength())
  300.       return GetItemPath(parent_it)+st+slash;
  301.     else
  302.       return GetItemPath(parent_it);
  303.   } else
  304.     return "";
  305. }
  306.  
  307. HTREEITEM CDirTreeView::GetPathItem(CString path,BOOL open,BOOL nofail,BOOL nohide,HTREEITEM rootposition) {
  308.   CTreeCtrl& tree=GetTreeCtrl();
  309.   if (!tree) return NULL;   /* error */
  310.   //
  311.   HTREEITEM return_value=NULL;
  312.   //
  313.   CString left="",right="";
  314.   int pos=path.Find('\\');
  315.   if (pos<0)
  316.     left=path;
  317.   else {
  318.     left=path.Left(pos);
  319.     right=path.Mid(pos+1);
  320.   }
  321.  
  322.   if (!nohide)
  323.     tree.ModifyStyle(WS_VISIBLE,0);
  324.   
  325.   HTREEITEM position;
  326.   if (!rootposition) {
  327.     rootposition=tree.GetRootItem();
  328.     /* position initiale */
  329.     position=rootposition;
  330.   } else {
  331.     // Ouvrir?
  332.     if (open) {
  333.       if (tree.ItemHasChildren(rootposition)) {        /* si enfants */
  334.         if (!(tree.GetItemState(rootposition,TVIF_STATE) & TVIS_EXPANDED)) {    /* si non ouvert */
  335.           /*tree.SetItemState(rootposition,TVIF_STATE,
  336.             tree.GetItemState(rootposition,TVIF_STATE) | TVIS_EXPANDED);
  337.             */
  338.           tree.Expand(rootposition,TVE_EXPAND);
  339.           RefreshDir(rootposition,TRUE);
  340.         }
  341.       }
  342.       
  343.     }
  344.  
  345.     /* position initiale */
  346.     position=tree.GetChildItem(rootposition);
  347.   }
  348.  
  349.   left.MakeLower();
  350.   while(position) {
  351.     CString st=GetItemName(position);
  352.     st.MakeLower();
  353.     if (st==left) {
  354.       if (right.GetLength())
  355.         position=GetPathItem(right,open,nofail,TRUE,position);
  356.       else
  357.         return_value=position;      // trouvÈ
  358.       position=NULL;
  359.     }
  360.     if (position)
  361.       position=tree.GetNextSiblingItem(position);
  362.   }
  363.  
  364.   // liste visible
  365.   if (!nohide) {
  366.     tree.ModifyStyle(0,WS_VISIBLE);
  367.     //RedrawWindow();
  368.     tree.GetParent()->RedrawWindow();
  369.   }
  370.   if (return_value)
  371.     return return_value;
  372.   else if (nofail)
  373.     return rootposition;
  374.   else
  375.     return NULL;
  376. }
  377.  
  378. BOOL CDirTreeView::EnsureVisible(CString path) {
  379.   if (!GetTreeCtrl()) return FALSE;   /* error */
  380. #if 0
  381.   /* Lancer refresh en arriËre plan */
  382.   refreshPath=path;
  383.   StopTimer();
  384.   AfxBeginThread(CDirTreeViewRefresh,this);
  385.   return TRUE;
  386. #else
  387.   CWaitCursor wait;
  388.   HTREEITEM pos=GetPathItem(path,TRUE,TRUE);
  389.   if (pos) {
  390.     GetTreeCtrl().EnsureVisible(pos);
  391.   } else
  392.     return FALSE;
  393.   return TRUE;
  394. #endif
  395. }
  396.  
  397. BOOL CDirTreeView::EnsureVisibleBl(CString path) {
  398.   if (!GetTreeCtrl()) return FALSE;   /* error */
  399.   CWaitCursor wait;
  400.   int return_value=TRUE;
  401.   StopTimer();
  402.   HTREEITEM pos=GetPathItem(path,TRUE,TRUE);
  403.   if (pos) {
  404.     GetTreeCtrl().EnsureVisible(pos);
  405.   } else
  406.     return_value=FALSE;
  407.   StartTimer();
  408.   return return_value;
  409. }
  410.  
  411. void CDirTreeView::RefreshPos(HTREEITEM position) {
  412.   RefreshDir(position);
  413. }
  414.  
  415. BOOL CDirTreeView::RefreshDir(HTREEITEM position,BOOL nohide) {
  416.   CTreeCtrl& tree=GetTreeCtrl();
  417.   if (!tree) return FALSE;   /* error */
  418.  
  419.   CWaitCursor wait;
  420.   CString path=GetItemPath(position);
  421.   CString backup_visibles="\n";
  422.  
  423.   // Pour FindFirstFile/FindNextFile
  424.   WIN32_FIND_DATA find;
  425.   int type;
  426.   HANDLE h = FindFirstFile(path+"*.*",&find);
  427.  
  428.   // accessible
  429.   if (h!=INVALID_HANDLE_VALUE) {
  430.     // liste invisible
  431.     if (!nohide)
  432.       tree.ModifyStyle(WS_VISIBLE,0);
  433.  
  434.     { // backuper ÈlÈments visibles
  435.       HTREEITEM it=tree.GetChildItem(position);
  436.       int backup_visibles_count=0;
  437.       while(it) {
  438.         if (tree.ItemHasChildren(it)) {        /* si enfants */
  439.           if (tree.GetItemState(it,TVIF_STATE) & TVIS_EXPANDED) {    /* si ouvert */
  440.             backup_visibles+=(GetItemPath(it)+"\n");
  441.             backup_visibles_count++;
  442.           }
  443.         }
  444.         it=tree.GetNextVisibleItem(it);
  445.       }
  446.       if (!backup_visibles_count)
  447.         backup_visibles="";
  448.     }
  449.  
  450.     {  // effacer la liste
  451.       HTREEITEM it;
  452.       while(it=tree.GetChildItem(position))
  453.         tree.DeleteItem(it);
  454.     }
  455.     
  456.     // chargement de la liste
  457.     HTREEITEM last_dir_it=tree.GetRootItem();
  458.     for(type=0;type<2;type++) {
  459.       if (h != INVALID_HANDLE_VALUE) {
  460.         do {
  461.           if (!(find.dwFileAttributes  & (FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN))) {
  462.             if (strcmp(find.cFileName,"..")) {
  463.               if (strcmp(find.cFileName,".")) {
  464.                 HTREEITEM it=NULL;
  465.                 if (find.dwFileAttributes  & FILE_ATTRIBUTE_DIRECTORY ) {
  466.                   if (type==0) {
  467.                     if (IsWindow(tree.m_hWnd)) {
  468.                       it=tree.InsertItem(find.cFileName,position);
  469.                       tree.InsertItem("expanding..",it,TVI_SORT);
  470.                     }
  471.                   }
  472.                 } else {
  473.                   if (type==1) {
  474.                     if (IsWindow(tree.m_hWnd))
  475.                       it=tree.InsertItem(find.cFileName,position,last_dir_it);
  476.                   }
  477.                 }
  478.                 // changer icone
  479.                 if (it) {
  480.                   SHFILEINFO info;
  481.                   SHGetFileInfo(path+find.cFileName,0,&info,sizeof(info),SHGFI_SYSICONINDEX);
  482.                   //SHGetFileInfo(path+find.cFileName,0,&info,sizeof(info),SHGFI_SMALLICON | SHGFI_SYSICONINDEX | SHGFI_TYPENAME | SHGFI_SHELLICONSIZE | SHGFI_DISPLAYNAME | SHGFI_ATTRIBUTES); 
  483.                   if (IsWindow(tree.GetSafeHwnd()))
  484.                     tree.SetItemImage(it,info.iIcon,info.iIcon);
  485.                 }
  486.               }
  487.             }
  488.           }
  489.         } while(FindNextFile(h,&find));
  490.         FindClose(h);
  491.       }
  492.       if (type==0)
  493.         h = FindFirstFile(path+"*.*",&find);
  494.     }
  495.  
  496.     // restaurer ÈlÈments visibles
  497.     RestoreVisibles(position,backup_visibles);
  498.  
  499.     // liste visible
  500.     if (!nohide)
  501.       tree.ModifyStyle(0,WS_VISIBLE);
  502.   }/* **OLD 
  503.   else
  504.     tree.Expand(position,TVE_COLLAPSE);
  505.    */
  506.  
  507.   // Redessiner
  508.   if (!nohide)
  509.     GetParent()->RedrawWindow();
  510.   return (h!=INVALID_HANDLE_VALUE);
  511. }
  512.  
  513. void CDirTreeView::RestoreVisibles(HTREEITEM position,CString& backup_visibles) {
  514.   CTreeCtrl& tree=GetTreeCtrl();
  515.   if (!tree) return;   /* error */
  516.  
  517.   if (backup_visibles.GetLength()) {
  518.     // rÈouvrir les ÈlÈments visibles
  519.     HTREEITEM it=tree.GetChildItem(position);
  520.     while(it) {
  521.       if (backup_visibles.Find("\n"+GetItemPath(it)+"\n")>=0) {
  522.         tree.Expand(it,TVE_EXPAND);
  523.         RefreshDir(it,TRUE);       /* car appelÈ par RefreshDir lui mÍme */
  524.         RestoreVisibles(it,backup_visibles);
  525.       }
  526.       it=tree.GetNextSiblingItem(it);
  527.     }
  528.   }
  529. }
  530.  
  531.  
  532.  
  533. void CDirTreeView::StartTimer() {
  534.   if (!timer) {
  535.     //whandle=FindFirstChangeNotification("C:\\",TRUE,FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME);
  536.     BuildTrackHandles();
  537.     timer=SetTimer(WM_TIMER,1000,NULL);
  538.   }
  539. }
  540. void CDirTreeView::StopTimer() {
  541.   if (timer) {
  542.     DestroyTrackHandles();
  543.     KillTimer(timer);
  544.     timer=0;
  545.   }
  546. }
  547.  
  548. void CDirTreeView::DestroyTrackHandles() 
  549. {
  550.   /* Fermer handles actuels */
  551.   if (count_whandle) {
  552.     int i;
  553.     for(i=0;i<count_whandle;i++)
  554.       FindCloseChangeNotification(whandle[i]);
  555.     count_whandle=0;
  556.   }
  557. }
  558.  
  559. void CDirTreeView::BuildTrackHandles() 
  560. {
  561.   if (!GetTreeCtrl()) return;   /* error */
  562.   DestroyTrackHandles();
  563.   /* Lecture ÈlÈments du root visibles (non, c'est pas rÈcursif vu que ce sont les Èlts visibles) */
  564.   CTreeCtrl& it=GetTreeCtrl();
  565.   HTREEITEM pos=it.GetFirstVisibleItem();
  566.   while(pos) {
  567.     CString path=GetItemPath(pos);
  568.     CFileStatus status;
  569.     if (it.ItemHasChildren(pos)) {        /* surveiller si enfants */
  570.       if (it.GetItemState(pos,TVIF_STATE) & TVIS_EXPANDED) {    /* si ouvert */
  571.         if (CFile::GetStatus(path.Left(path.GetLength()-1),status)) {   // rÈpertoire (note: path sans le / final)
  572.           if (status.m_attribute & 0x10 ) {       /* directory = 0x10 */
  573.             whandle[count_whandle]=FindFirstChangeNotification(path,FALSE,FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME);
  574.             if (whandle[count_whandle] != INVALID_HANDLE_VALUE) {
  575.               pos_whandle[count_whandle]=pos;
  576.               count_whandle++;
  577.             }
  578.           }
  579.         }
  580.       }
  581.     }
  582.     pos=it.GetNextVisibleItem(pos);
  583.   }
  584.  
  585. }
  586.  
  587. void CDirTreeView::DoTrackHandles() 
  588. {
  589.   CTreeCtrl& tree=GetTreeCtrl();
  590.   if (!tree) return;   /* error */
  591.  
  592.   if (count_whandle) {
  593.     int r=(WaitForMultipleObjects(count_whandle,whandle,FALSE,0)-WAIT_OBJECT_0);
  594.     if ( (r>=0) && (r<count_whandle) ) {      // un item a changÈ
  595.       DestroyTrackHandles();
  596.       HTREEITEM pos=pos_whandle[r];
  597.       RefreshPos(pos);
  598.       tree.SetItemState(pos,TVIS_BOLD,TVIS_BOLD);
  599.       BuildTrackHandles();      /* probleme: on va en rater certains.. */ 
  600.       //FindNextChangeNotification(whandle[r]);
  601.     }
  602.     /*
  603.     int i;
  604.     for(i=0;i<count_whandle;i++)
  605.       FindNextChangeNotification(whandle[i]);
  606.     */
  607.   }
  608. }
  609.  
  610. void CDirTreeView::OnTimer(UINT nIDEvent) 
  611. {
  612.   DoTrackHandles();
  613.   CTreeView::OnTimer(nIDEvent);
  614. }
  615.  
  616. void CDirTreeView::OnShowWindow(BOOL bShow, UINT nStatus) 
  617. {
  618.   static BOOL detach_flag=FALSE;
  619.   if (detach_flag == bShow) return;
  620.   detach_flag=bShow;
  621.  
  622.   if (bShow) {
  623.     HIMAGELIST hSystemImageList;
  624.     SHFILEINFO SHFileInfo;
  625.     hSystemImageList = (HIMAGELIST)SHGetFileInfo("", 0, &SHFileInfo, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
  626.     if (!hSystemImageList) {
  627.       MessageBox("Error: SHGetFileInfo");
  628.       //return;
  629.     } else {
  630.       imagelist.Attach(hSystemImageList);
  631.     }
  632.   } else {
  633.     if (imagelist.m_hImageList) {
  634.       imagelist.Detach();
  635.       imagelist.m_hImageList=NULL;
  636.     }
  637.   }
  638.   //
  639.   CTreeView::OnShowWindow(bShow, nStatus);
  640.   if (bShow)
  641.     StartTimer();
  642.   else
  643.     StopTimer();
  644. }
  645.  
  646.  
  647. void CDirTreeView::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult) 
  648. {
  649.     TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
  650.     // TODO: Add your control notification handler code here
  651.  
  652.   if (pTVDispInfo->item.mask & TVIF_TEXT) {
  653.     if (pTVDispInfo->item.pszText) {
  654.       if (strlen(pTVDispInfo->item.pszText)) {
  655.         CString path=GetItemPath(pTVDispInfo->item.hItem);
  656.         if (path.Right(1)=="\\")
  657.           path=path.Left(path.GetLength()-1);
  658.         CString newpath=path.Left(path.ReverseFind('\\')+1)+pTVDispInfo->item.pszText;
  659.         if (path != newpath) {
  660.           if (!MoveFile(path,newpath)) {
  661.             AfxMessageBox("Unable to rename "+path+" to "+newpath+"!");
  662.           } else {
  663.             GetTreeCtrl().SetItemText(pTVDispInfo->item.hItem,pTVDispInfo->item.pszText);
  664.           }
  665.         }
  666.       }
  667.     }
  668.   }
  669.   
  670.  
  671.     *pResult = 0;
  672. }
  673.  
  674. void CDirTreeView::OnKeydown(NMHDR* pNMHDR, LRESULT* pResult) 
  675. {
  676.     TV_KEYDOWN* pTVKeyDown = (TV_KEYDOWN*)pNMHDR;
  677.   HTREEITEM selected=GetTreeCtrl().GetSelectedItem();
  678.     *pResult = 0;
  679.     
  680.   int key=pTVKeyDown->wVKey ;
  681.   switch(key) {
  682.   case 32:
  683.     if (selected) {
  684.       GetTreeCtrl().Expand(selected,TVE_TOGGLE);
  685.          *pResult = -1;
  686.     }
  687.     break;
  688.   case 13: case 10:
  689.     if (selected) {
  690.       GetTreeCtrl().Expand(selected,TVE_TOGGLE);
  691.          *pResult = -1;
  692.     }
  693.     break;
  694.   /*default:
  695.     printf("\a");
  696.     break;
  697.   */
  698.   }
  699.  
  700. }
  701.  
  702.  
  703.  
  704. /*
  705. IMPLEMENT_DYNAMIC(CDirTreeViewShellEx, CWinThread)
  706.  
  707. /////////////////////////////////////////////////////////////////////////////
  708. // CDirTreeViewShellEx
  709. BOOL CDirTreeViewShellEx::InitInstance() {
  710.   if (!ShellExecute(NULL,NULL,File,NULL,NULL,SW_SHOWNORMAL)) {
  711.   }
  712.   return 0;
  713. }
  714. */
  715. UINT CDirTreeViewShellEx( LPVOID pP ) {
  716.   CWaitCursor wait;
  717.   CString* File=(CString*) pP;
  718.   if (!ShellExecute(NULL,"open",*File,NULL,NULL,SW_SHOWNORMAL)) {
  719.   }
  720.   delete File;
  721.   return 0;
  722. }
  723.  
  724. UINT CDirTreeViewRefresh( LPVOID pP ) {
  725.   CDirTreeView* _this=(CDirTreeView*) pP;
  726.   if (!_this->redraw_in_progress) {
  727.     _this->redraw_in_progress=1;
  728.     _this->EnsureVisibleBl(_this->refreshPath);
  729.     _this->redraw_in_progress=0;
  730.   }
  731.   return 0;
  732. }
  733.  
  734.  
  735.  
  736. void CDirTreeView::OnKillFocus(CWnd* pNewWnd) 
  737. {
  738.     CTreeView::OnKillFocus(pNewWnd);
  739.     
  740.     CWnd* top_window=this;
  741.     while(top_window->GetParent())
  742.       top_window=top_window->GetParent();
  743.     ((CMainFrame*)top_window)->m_wndStatusBar.SetWindowText("");
  744.     
  745. }
  746.  
  747.